//-------------------------------------------------------------------------------------
// <copyright file="CompileMsi.cs" company="Microsoft">
//      Copyright (c) Microsoft Corporation. All rights reserved.
//      THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
//      EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
//      WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// </copyright>
// <author>Greg Beech</author>
// <email>gregbee@microsoft.com</email>
// <date>2004-04-16</date>
// <summary>
//      Compiles an intermediate .wixobj file for an MSI from Wix input files.
// </summary>  
//-------------------------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.Wix
{
    using System.IO;
    using System.Text;

    /// <summary>
    /// Compiles an intermediate <b>*.wixobj</b> file for an MSI from Wix <b>*.wxs</b> input files. This
    /// intermediate file can then be used with the <see cref="Microsoft.Sdc.Tasks.Wix.LinkMsi"/>
    /// task to create a complete MSI package.
    /// </summary>
    /// <remarks>
    /// <para>
    /// <b>About Wix:</b> Wix was originally a Microsoft tool that has been released into the open source
    /// community under the Common Public License. The binaries and source code can be downloaded from
    /// <a href="http://sourceforge.net/projects/wix">SourceForge</a>.
    /// </para>
    /// <code><![CDATA[<CompileMsi SourceFiles="sourceFiles" OutputFile="outputFile" WixPath="wixPath" InformationLevel="informationLevel" WarningLevel="warningLevel" TreatWarningsAsErrors="treatWarningsAsErrors" AdditionalSearchPaths="additionalSearchPaths" CompilationParameters="compilationParameters" />]]></code>
    /// <para>where:</para>
    /// <para><i>sourceFiles (Required)</i></para>
    /// <para>
    /// A delimited list of the source files to generate the intermediate file from. These will normally have 
    /// the extension *.wxs. Please refer to the Wix documentation for the schema of these files.
    /// </para>
    /// <para><i>outputFile (Required)</i></para>
    /// <para>
    /// The path to the intermediate object file to produce. This should have the extension *.wixobj.
    /// </para>
    /// <para><i>wixPath (Required)</i></para>
    /// <para>
    /// The path to the directory that the Wix executables reside in.
    /// </para>
    /// <para><i>informationLevel</i></para>
    /// <para>
    /// An integer between zero (verbose information) and three (no information). The default is zero.
    /// </para>
    /// <para><i>warningLevel</i></para>
    /// <para>
    /// An integer between zero (all warnings) and three (no warnings). The default is zero.
    /// </para>
    /// <para><i>treatWarningsAsErrors</i></para>
    /// <para>
    /// <b>true</b> if warnings are treated as errors, or <b>false</b> otherwise. The default is <b>false</b>.
    /// </para>
    /// <para><i>additionalSearchPaths</i></para>
    /// <para>
    /// A delimited list of additional search paths for include files for the compiler.
    /// </para>
    /// <para><i>compilationParameters</i></para>
    /// <para>
    /// A delimited list of compilation parameters for the compiler, with each parameter in the format
    /// Name=Value.
    /// </para>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test">
    ///         <CompileMsi 
    ///             SourceFiles="SourceFile1.wxs;SourceFile2.wxs" 
    ///             OutputFile="OutputFile.wxsobj" 
    ///             WixPath="C:\Program Files\Wix" 
    ///             InformationLevel="1" 
    ///             WarningLevel="2" 
    ///             TreatWarningsAsErrors="true" 
    ///             AdditionalSearchPaths="C:\Build\Msi\Includes;C:\Build\Msi\References" 
    ///             CompilationParameters="debug=false;ieversion=6.0;winver=5.1" />
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>
    public sealed class CompileMsi : WixTaskBase
    {
        #region Member Variables

        private string[] additionalSearchPaths;
        private string[] compilationParameters;

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the additional search paths for include files for the compiler.
        /// </summary>
        /// <value>
        /// Additional search paths for include files for the compiler.
        /// </value>
        public string[] AdditionalSearchPaths
        {
            get { return this.additionalSearchPaths ?? new string[0]; }

            set { this.additionalSearchPaths = value; }
        }

        /// <summary>
        /// Gets or sets the compilation parameters for the compiler, with each parameter in the format
        /// Name=Value.
        /// </summary>
        /// <value>
        /// Compilation parameters for the compiler in the format Name=Value.
        /// </value>
        public string[] CompilationParameters
        {
            get { return this.compilationParameters ?? new string[0]; }
            set { this.compilationParameters = value; }
        }

        #endregion

        #region Protected Methods

        /// <summary>
        /// Executes the task.
        /// </summary>
        protected override void InternalExecute()
        {
            StringBuilder argumentsBuilder = new StringBuilder("-nologo ");
            if (this.compilationParameters != null && this.compilationParameters.Length > 0)
            {
                foreach (string parameter in this.compilationParameters)
                {
                    argumentsBuilder.Append(EscapeArgument(string.Concat("-d", parameter)) + " ");
                }
            }

            if (this.additionalSearchPaths != null && this.additionalSearchPaths.Length > 0)
            {
                foreach (string searchPath in this.additionalSearchPaths)
                {
                    argumentsBuilder.Append(EscapeArgument(string.Concat("-I", searchPath, " ")));
                }
            }

            this.AppendInformationAndWarningLevelArguments(argumentsBuilder);
            argumentsBuilder.Append(string.Concat("-out ", EscapeArgument(this.OutputFile), " "));
            foreach (string sourceFile in this.SourceFiles)
            {
                string extension;
                if ((extension = Path.GetExtension(sourceFile)) != ".wxs")
                {
                    this.Log.LogWarning("Source file with unexpected extension encountered. Expected *.wxs but actual extension is *" + extension);
                }

                argumentsBuilder.Append(string.Concat(EscapeArgument(sourceFile), " "));
            }

            string executablePath = Path.Combine(this.WixPath, WixTaskBase.CompilerName);
            string arguments = argumentsBuilder.ToString(0, argumentsBuilder.Length - 1);
            this.RunWixProcess(executablePath, arguments);
        }

        #endregion
    }
}